home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / misc / o-z / x-windows / mesa-amiwin / src / accum.c next >
Encoding:
C/C++ Source or Header  |  1995-11-17  |  10.3 KB  |  389 lines

  1. /* accum.c */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * Accumulation buffer.
  26.  */
  27.  
  28.  
  29. /*
  30. $Id: accum.c,v 1.14 1995/10/13 22:42:57 brianp Exp $
  31.  
  32. $Log: accum.c,v $
  33.  * Revision 1.14  1995/10/13  22:42:57  brianp
  34.  * use new DD.set_buffer function
  35.  *
  36.  * Revision 1.13  1995/09/18  14:20:50  brianp
  37.  * call DD.write_span_color with NULL mask, temporary hack
  38.  *
  39.  * Revision 1.12  1995/08/31  21:26:18  brianp
  40.  * use DD.read_color_span instead of dd_read_color_span
  41.  *
  42.  * Revision 1.11  1995/07/24  20:34:16  brianp
  43.  * replaced memset() with MEMSET() and memcpy() with MEMCPY()
  44.  *
  45.  * Revision 1.10  1995/06/12  15:35:00  brianp
  46.  * changed color arrays to GLubyte
  47.  *
  48.  * Revision 1.9  1995/05/22  21:02:41  brianp
  49.  * Release 1.2
  50.  *
  51.  * Revision 1.8  1995/05/12  19:22:23  brianp
  52.  * added #include "macros.h"
  53.  *
  54.  * Revision 1.7  1995/05/12  19:20:19  brianp
  55.  * replaced CC.Mode!=0 with INSIDE_BEGIN_END
  56.  *
  57.  * Revision 1.6  1995/04/11  14:03:27  brianp
  58.  * changed (*CC.write...) to (*DD.write...)
  59.  *
  60.  * Revision 1.5  1995/03/30  21:06:50  brianp
  61.  * updated to use pointers to CC.write_* functions
  62.  *
  63.  * Revision 1.4  1995/03/24  15:28:22  brianp
  64.  * replaced ACCUM_BITS with ACC_TYPE
  65.  *
  66.  * Revision 1.3  1995/03/13  20:54:27  brianp
  67.  * added read buffer logic
  68.  *
  69.  * Revision 1.2  1995/03/04  19:29:44  brianp
  70.  * 1.1 beta revision
  71.  *
  72.  * Revision 1.1  1995/02/24  14:14:02  brianp
  73.  * Initial revision
  74.  *
  75.  */
  76.  
  77.  
  78. #include <stdlib.h>
  79. #include <string.h>
  80. #include "context.h"
  81. #include "dd.h"
  82. #include "list.h"
  83. #include "macros.h"
  84.  
  85.  
  86.  
  87. /** THIS IS A HACK!  See drawpix.c for more info. **/
  88. #ifdef SHM
  89. #  define MASK  NULL
  90. #else
  91. #  define MASK  mask
  92. #endif
  93.  
  94.  
  95.  
  96. void glClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
  97. {
  98.    if (CC.CompileFlag) {
  99.       gl_save_clearaccum( red, green, blue, alpha );
  100.    }
  101.    if (CC.ExecuteFlag) {
  102.       if (INSIDE_BEGIN_END) {
  103.      gl_error( GL_INVALID_OPERATION, "glAccum" );
  104.      return;
  105.       }
  106.       CC.Accum.ClearColor[0] = CLAMP( red, -1.0, 1.0 );
  107.       CC.Accum.ClearColor[1] = CLAMP( green, -1.0, 1.0 );
  108.       CC.Accum.ClearColor[2] = CLAMP( blue, -1.0, 1.0 );
  109.       CC.Accum.ClearColor[3] = CLAMP( alpha, -1.0, 1.0 );
  110.    }
  111. }
  112.  
  113.  
  114.  
  115.  
  116. void gl_accum( GLenum op, GLfloat value )
  117. {
  118.    GLuint xpos, ypos, width, height;
  119.    GLfloat acc_scale;
  120.  
  121.    if (sizeof(ACC_TYPE)==1) {
  122.       acc_scale = 127.0;
  123.    }
  124.    else {
  125.       /* size of ACC_TYPE==2 */
  126.       acc_scale = 32767.0;
  127.    }
  128.  
  129.    if (INSIDE_BEGIN_END) {
  130.       gl_error( GL_INVALID_OPERATION, "glAccum" );
  131.       return;
  132.    }
  133.  
  134.    if (!CC.AccumBuffer) {
  135.       /* allocate accumulation buffer if not already present */
  136.       CC.AccumBuffer = (ACC_TYPE *)
  137.         malloc( CC.BufferWidth * CC.BufferHeight * 4 * sizeof(ACC_TYPE) );
  138.       if (!CC.AccumBuffer) {
  139.      /* unable to setup accumulation buffer */
  140.      gl_error( GL_OUT_OF_MEMORY, "glAccum" );
  141.      return;
  142.       }
  143.    }
  144.  
  145.    /* Determine region to operate upon. */
  146.    if (CC.Scissor.Enabled) {
  147.       xpos = CC.Scissor.X;
  148.       ypos = CC.Scissor.Y;
  149.       width = CC.Scissor.Width;
  150.       height = CC.Scissor.Height;
  151.    }
  152.    else {
  153.       /* whole window */
  154.       xpos = 0;
  155.       ypos = 0;
  156.       width = CC.BufferWidth;
  157.       height = CC.BufferHeight;
  158.    }
  159.  
  160.    switch (op) {
  161.       case GL_ADD:
  162.          {
  163.         ACC_TYPE ival, *acc;
  164.         GLuint i, j;
  165.  
  166.         ival = (ACC_TYPE) (value * acc_scale);
  167.         for (j=0;j<height;j++) {
  168.            acc = CC.AccumBuffer + ( ypos * CC.BufferWidth + xpos ) * 4;
  169.            for (i=0;i<width;i++) {
  170.           *acc += ival;      acc++;   /* red */
  171.           *acc += ival;      acc++;   /* green */
  172.           *acc += ival;      acc++;   /* blue */
  173.           *acc += ival;      acc++;   /* alpha */
  174.            }
  175.            ypos++;
  176.         }
  177.      }
  178.      break;
  179.       case GL_MULT:
  180.      {
  181.         ACC_TYPE *acc;
  182.         GLuint i, j;
  183.  
  184.         for (j=0;j<height;j++) {
  185.            acc = CC.AccumBuffer + ( ypos * CC.BufferWidth + xpos ) * 4;
  186.            for (i=0;i<width;i++) {
  187.           *acc = (ACC_TYPE) ( (GLfloat) *acc * value );      acc++; /*r*/
  188.           *acc = (ACC_TYPE) ( (GLfloat) *acc * value );      acc++; /*g*/
  189.           *acc = (ACC_TYPE) ( (GLfloat) *acc * value );      acc++; /*g*/
  190.           *acc = (ACC_TYPE) ( (GLfloat) *acc * value );      acc++; /*a*/
  191.            }
  192.            ypos++;
  193.         }
  194.      }
  195.      break;
  196.       case GL_ACCUM:
  197.      {
  198.         ACC_TYPE *acc;
  199.         GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  200.         GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  201.         GLfloat rscale, gscale, bscale, ascale;
  202.         GLuint i, j;
  203.  
  204.         (void) (*DD.set_buffer)( CC.Pixel.ReadBuffer );
  205.  
  206.         /* Accumulate */
  207.         rscale = value * acc_scale / CC.RedScale;
  208.         gscale = value * acc_scale / CC.GreenScale;
  209.         bscale = value * acc_scale / CC.BlueScale;
  210.         ascale = value * acc_scale / CC.AlphaScale;
  211.         for (j=0;j<height;j++) {
  212.            (*DD.read_color_span)( width, xpos, ypos,
  213.                                       red, green, blue, alpha);
  214.            acc = CC.AccumBuffer + ( ypos * CC.BufferWidth + xpos ) * 4;
  215.            for (i=0;i<width;i++) {
  216.           *acc += (ACC_TYPE) ( (GLfloat) red[i]   * rscale );  acc++;
  217.           *acc += (ACC_TYPE) ( (GLfloat) green[i] * gscale );  acc++;
  218.           *acc += (ACC_TYPE) ( (GLfloat) blue[i]  * bscale );  acc++;
  219.           *acc += (ACC_TYPE) ( (GLfloat) alpha[i] * ascale );  acc++;
  220.            }
  221.            ypos++;
  222.         }
  223.  
  224.         (void) (*DD.set_buffer)( CC.Color.DrawBuffer );
  225.      }
  226.      break;
  227.       case GL_LOAD:
  228.      {
  229.         ACC_TYPE *acc;
  230.         GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  231.         GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  232.         GLfloat rscale, gscale, bscale, ascale;
  233.         GLuint i, j;
  234.  
  235.         (void) (*DD.set_buffer)( CC.Pixel.ReadBuffer );
  236.  
  237.         /* Load accumulation buffer */
  238.         rscale = value * acc_scale / CC.RedScale;
  239.         gscale = value * acc_scale / CC.GreenScale;
  240.         bscale = value * acc_scale / CC.BlueScale;
  241.         ascale = value * acc_scale / CC.AlphaScale;
  242.         for (j=0;j<height;j++) {
  243.            (*DD.read_color_span)( width, xpos, ypos,
  244.                                       red, green, blue, alpha);
  245.            acc = CC.AccumBuffer + ( ypos * CC.BufferWidth + xpos ) * 4;
  246.            for (i=0;i<width;i++) {
  247.           *acc++ = (ACC_TYPE) ( (GLfloat) red[i]   * rscale );
  248.           *acc++ = (ACC_TYPE) ( (GLfloat) green[i] * gscale );
  249.           *acc++ = (ACC_TYPE) ( (GLfloat) blue[i]  * bscale );
  250.           *acc++ = (ACC_TYPE) ( (GLfloat) alpha[i] * ascale );
  251.            }
  252.            ypos++;
  253.         }
  254.  
  255.         (void) (*DD.set_buffer)( CC.Color.DrawBuffer );
  256.      }
  257.      break;
  258.       case GL_RETURN:
  259.      {
  260.         GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  261.         GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  262.         GLubyte mask[MAX_WIDTH];
  263.         ACC_TYPE *acc;
  264.         GLfloat rscale, gscale, bscale, ascale;
  265.         GLint rmax, gmax, bmax, amax;
  266.         GLuint i, j;
  267.  
  268.         MEMSET( mask, 1, width );  /* set write mask to all 1's */
  269.         rscale = value / acc_scale * CC.RedScale;
  270.         gscale = value / acc_scale * CC.GreenScale;
  271.         bscale = value / acc_scale * CC.BlueScale;
  272.         ascale = value / acc_scale * CC.AlphaScale;
  273.         rmax = (GLint) CC.RedScale;
  274.         gmax = (GLint) CC.GreenScale;
  275.         bmax = (GLint) CC.BlueScale;
  276.         amax = (GLint) CC.AlphaScale;
  277.         for (j=0;j<height;j++) {
  278.            acc = CC.AccumBuffer + ( ypos * CC.BufferWidth + xpos ) * 4;
  279.            for (i=0;i<width;i++) {
  280.           GLint r, g, b, a;
  281.           r = (GLint) ( (GLfloat) (*acc++) * rscale );
  282.           g = (GLint) ( (GLfloat) (*acc++) * gscale );
  283.           b = (GLint) ( (GLfloat) (*acc++) * bscale );
  284.           a = (GLint) ( (GLfloat) (*acc++) * ascale );
  285.           red[i]   = CLAMP( r, 0, rmax );
  286.           green[i] = CLAMP( g, 0, gmax );
  287.           blue[i]  = CLAMP( b, 0, bmax );
  288.           alpha[i] = CLAMP( a, 0, amax );
  289.            }
  290.            (*DD.write_color_span)( width, xpos, ypos,
  291.                        red, green, blue, alpha, MASK );
  292.            ypos++;
  293.         }
  294.      }
  295.      break;
  296.       default:
  297.          gl_error( GL_INVALID_ENUM, "glAccum" );
  298.    }
  299. }
  300.  
  301.  
  302.  
  303.  
  304. void glAccum( GLenum op, GLfloat value )
  305. {
  306.    if (CC.ExecuteFlag) {
  307.       gl_accum( op, value );
  308.    }
  309.    if (CC.CompileFlag) {
  310.       gl_save_accum( op, value );
  311.    }
  312. }
  313.  
  314.  
  315.  
  316. /*
  317.  * Clear the accumulation buffer.
  318.  */
  319. void gl_clear_accum_buffer( void )
  320. {
  321.    GLuint buffersize;
  322.    GLfloat acc_scale;
  323.  
  324.    if (sizeof(ACC_TYPE)==1) {
  325.       acc_scale = 127.0;
  326.    }
  327.    else {
  328.       /* size of ACC_TYPE==2 */
  329.       acc_scale = 32767.0;
  330.    }
  331.  
  332.  
  333.    buffersize = CC.BufferWidth * CC.BufferHeight;  /* number of pixels */
  334.  
  335.    if (!CC.AccumBuffer) {
  336.       /* try to alloc accumulation buffer */
  337.       CC.AccumBuffer = (ACC_TYPE *)
  338.                        malloc( buffersize * 4 * sizeof(ACC_TYPE) );
  339.    }
  340.  
  341.    if (CC.AccumBuffer) {
  342.       if (CC.Scissor.Enabled) {
  343.      /* Limit clear to scissor box */
  344.      ACC_TYPE r, g, b, a;
  345.      GLint x, y, i;
  346.      r = (ACC_TYPE) (CC.Accum.ClearColor[0] * acc_scale);
  347.      g = (ACC_TYPE) (CC.Accum.ClearColor[1] * acc_scale);
  348.      b = (ACC_TYPE) (CC.Accum.ClearColor[2] * acc_scale);
  349.      a = (ACC_TYPE) (CC.Accum.ClearColor[3] * acc_scale);
  350.      for (y=CC.Scissor.Ymin; y<=CC.Scissor.Ymax; y++) {
  351.         for (x=CC.Scissor.Xmin; x<=CC.Scissor.Xmax; x++) {
  352.            i = 4 * (y * CC.BufferWidth + x);
  353.            CC.AccumBuffer[i+0] = r;
  354.            CC.AccumBuffer[i+1] = g;
  355.            CC.AccumBuffer[i+2] = b;
  356.            CC.AccumBuffer[i+3] = a;
  357.         }
  358.      }
  359.       }
  360.       else {
  361.      /* clear whole buffer */
  362.      if (CC.Accum.ClearColor[0]==0.0 &&
  363.          CC.Accum.ClearColor[1]==0.0 &&
  364.          CC.Accum.ClearColor[2]==0.0 &&
  365.          CC.Accum.ClearColor[3]==0.0) {
  366.         /* Black */
  367.         MEMSET( CC.AccumBuffer, 0, buffersize * 4 * sizeof(ACC_TYPE) );
  368.      }
  369.      else {
  370.         /* Not black */
  371.         ACC_TYPE *acc, r, g, b, a;
  372.         GLuint i;
  373.  
  374.         acc = CC.AccumBuffer;
  375.         r = (ACC_TYPE) (CC.Accum.ClearColor[0] * acc_scale);
  376.         g = (ACC_TYPE) (CC.Accum.ClearColor[1] * acc_scale);
  377.         b = (ACC_TYPE) (CC.Accum.ClearColor[2] * acc_scale);
  378.         a = (ACC_TYPE) (CC.Accum.ClearColor[3] * acc_scale);
  379.         for (i=0;i<buffersize;i++) {
  380.            *acc++ = r;
  381.            *acc++ = g;
  382.            *acc++ = b;
  383.            *acc++ = a;
  384.         }
  385.      }
  386.       }
  387.    }
  388. }
  389.